package org.zhc.service.impl;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.zhc.constant.Constants;
import org.zhc.context.ActionContext;
import org.zhc.po.Action;
import org.zhc.po.Property;
import org.zhc.po.Result;
import org.zhc.service.LoadConfigService;


public class LoadXMLConfig implements LoadConfigService {

	private static final Logger logger = Logger
			.getLogger(LoadXMLConfig.class.getName());

	/**
	 * 加载action的XML
	 * 
	 * @param xmlInputStream
	 *            配置文件的InputStream
	 */
	@Override
	@SuppressWarnings("unchecked")
	public void loadAcionConfig(InputStream xmlInputStream)
			throws DocumentException {
		SAXReader saxReader = new SAXReader();
		Document doc = saxReader.read(xmlInputStream);
		Element root = doc.getRootElement();
		List<Element> packageList = root.selectNodes("//package");
		for (Element elm : packageList) {
			String namespace = elm.attributeValue("namespace");
			if (namespace == null) {
				namespace = "/";
			}
			ActionContext.addNamespace(namespace, loadActionNodes(elm));
		}
	}

	/**
	 * 加载一个package节点下面所有的ACTION节点信息
	 * 
	 * @param packageElement
	 *            一个package节点
	 * @return java.util.Map<String,Action>
	 *         返回一个package节点下面所有的action节点，key为namespage,value为action
	 */
	@SuppressWarnings("unchecked")
	private Map<String, Action> loadActionNodes(Element packageElement) {
		Map<String, Action> actions = new HashMap<String, Action>();
		List<Element> actionElms = packageElement.selectNodes("action");
		for (Element elm : actionElms) {
			if (elm.attributeValue("name") != null) {
				String method = elm.attributeValue("method");
				if (method == null) {
					method = "execute";
				}
				Action action = new Action(elm.attributeValue("name"),
						elm.attributeValue("class"), method, loadResults(elm),
						loadParams(elm), loadActionAttrs(elm));
				actions.put(elm.attributeValue("name"), action);
			}
		}
		return actions;
	}

	/**
	 * 加载一个action下面所有的Result节点
	 * 
	 * @param atcionElement
	 *            一个action节点
	 * @return java.util.List<Result> 一个ACTION节点下面所有的Result节点
	 */
	@SuppressWarnings("unchecked")
	private List<Result> loadResults(Element atcionElement) {
		List<Result> results = new ArrayList<Result>();
		List<Element> resultElms = atcionElement.selectNodes("result");
		if (resultElms != null) {
			for (Element elm : resultElms) {
				String value = elm.attributeValue("value");
				String type = elm.attributeValue("type");
				if (type == null) {
					type = Constants.FORWARD;
				}
				List<Element> pros = elm.selectNodes("property");
				Node attrNode = elm.selectSingleNode("attribute");
				Result result = null;
				if (attrNode != null) {// 如果存在attribute节点，那么一定存在property节点
					result = new Result(value, type, loadProperties(elm),
							loadResultAttrs(elm));
				} else {// 如果没有attribute节点，就不确定是否存在property节点
					if (pros != null && pros.size() > 0) {// 如果存在property节点
						result = new Result(value, type, loadProperties(elm));
					} else {// 不存在attribute节点
						result = new Result(value, type, elm.getTextTrim());
					}
				}
				results.add(result);
			}
		}
		return results;
	}

	/**
	 * 加载一个Result节点下面所有的Property节点
	 * 
	 * @param resultElement
	 *            一个Result节点
	 * @return java.util.List<Property> 返回一个result节点下面所有的Property节点
	 */
	@SuppressWarnings("unchecked")
	private List<Property> loadProperties(Element resultElement) {
		List<Property> properties = new ArrayList<Property>();
		List<Element> proElms = resultElement.selectNodes("property");
		if (proElms != null) {
			for (Element elm : proElms) {
				Property property = new Property();
				property.setName(elm.attributeValue("name").trim());
				property.setContent(elm.getText() != null ? elm.getTextTrim()
						: "");
				properties.add(property);
			}
		}
		return properties;
	}

	private Set<String> loadParams(Element actionElement) {
		Set<String> params = new HashSet<String>();
		Node paramNode = actionElement.selectSingleNode("param");
		if (paramNode != null) {
			String _params[] = paramNode.getText().trim().split(",");
			if (_params != null) {
				params.addAll(Arrays.asList(_params));
			}
		}
		return params;
	}

	/**
	 * 加载action节点下面的attribute节点
	 * 
	 * @param actionElement
	 * @return
	 */
	private Set<String> loadActionAttrs(Element actionElement) {
		Set<String> attrs = new HashSet<String>();
		Node attrNode = actionElement.selectSingleNode("attribute");
		if (attrNode != null) {
			String _attrs[] = attrNode.getText().trim().split(",");
			if (_attrs != null) {
				attrs.addAll(Arrays.asList(_attrs));
			}
		}
		return attrs;
	}

	/**
	 * 加载result节点下面的attribute节点
	 * 
	 * @param resultElement
	 * @return
	 */
	private Set<String> loadResultAttrs(Element resultElement) {
		Set<String> attrs = new HashSet<String>();
		Node attrNode = resultElement.selectSingleNode("attribute");
		if (attrNode != null) {
			String _attrs[] = attrNode.getText().trim().split(",");
			if (_attrs != null) {
				attrs.addAll(Arrays.asList(_attrs));
			}
		}
		return attrs;
	}
}
